# encoding=utf-8
import datetime
import logging
import os
import traceback
import uuid
import numpy as np
import SimpleITK as sitk
from skimage import io
import cv2 as cv
import nibabel as nib
from logging.handlers import TimedRotatingFileHandler


class AppConfig:
    # 常规配置
    CONFIG_PATH = os.path.join(os.path.dirname(__file__))
    CACHE_PATH = os.path.join(CONFIG_PATH, "runtime-cache")
    LOGGER_PATH = os.path.join(CONFIG_PATH, "runtime-log")


def set_logger():
    logger = logging.getLogger()  # root
    logger.setLevel(logging.INFO)

    file_handler = TimedRotatingFileHandler(
        filename=os.path.join(AppConfig.LOGGER_PATH, "app-log"),
        when='D', interval=1
    )
    file_handler.suffix = "%Y-%m-%d.log"

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)

    logging_format = logging.Formatter(
        "%(asctime)s - %(filename)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s")

    file_handler.setFormatter(logging_format)
    console_handler.setFormatter(logging_format)

    logger.addHandler(file_handler)
    logger.addHandler(console_handler)


def generate_tmp_path():
    now_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    now_uuid = str(uuid.uuid1())
    save_path = os.path.join(AppConfig.CACHE_PATH, "optovue-nnunet-input-temp-cache", now_time, now_uuid)
    os.makedirs(save_path, exist_ok=True)
    return save_path


def convert2nifti(cv_path, spacing=(999, 1, 1)):
    temp_path = generate_tmp_path()
    try:
        file_name = os.path.basename(cv_path)
        stem, suffix = os.path.splitext(file_name)
        save_name_list = []

        # img = io.imread(cv_path)
        img = cv.imread(cv_path)
        if len(img.shape) == 2:  # 2d image with no color channels
            img = img[None, None]  # add dimensions
        else:
            assert len(img.shape) == 3, "image should be 3d with color channel last but has shape %s" % str(
                img.shape)
            img = img.transpose((2, 0, 1))
            img = img[:, None]

        # 这里拆分三个通道,分别进行保存
        for idx, e_img in enumerate(img):
            e_img = e_img.astype(np.uint32)

            itk_img = sitk.GetImageFromArray(e_img)
            itk_img.SetSpacing(list(spacing)[::-1])

            nii_name = "{}_{}.nii.gz".format(stem, idx)
            save_name_list.append(os.path.join(temp_path, nii_name))

            sitk.WriteImage(itk_img, os.path.join(temp_path, nii_name))

        return save_name_list
    except Exception as e:
        logging.exception(traceback.format_exc())
        return None


def convert2png(nii_path: str, axis: str = 'z'):
    npy_data = np.asanyarray(nib.load(nii_path).dataobj)
    npy_data = np.rot90(np.fliplr(npy_data))
    if axis == 'x':
        return npy_data[0, :, :]
    elif axis == 'y':
        return npy_data[:, 0, :]
    else:
        return npy_data[:, :, 0]
